package com.xin.utils
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	/**
	 * Tip工具
	 * @author daichangxin
	 * 
	 */
	public class TipUtils
	{
		private static var _instance:TipUtils;
		private var _tipContainer:DisplayObjectContainer;
		private var _showTimer:Timer;
		private var _hideTimer:Timer;
		
		private var _tipDic:Dictionary;
		private var _currentTipVo:TipVo;
		
		public function TipUtils()
		{
			if (_instance == null)
			{
				_instance = this;
				_tipDic = new Dictionary();
			}
		}
		
		/**
		 * 初始化Tip容器
		 */
		public function init(tipContainer:DisplayObjectContainer):void
		{
			_tipContainer = tipContainer;
			_showTimer = new Timer(100, 1);
			_showTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onShowTimerComplete);
			
			_hideTimer = new Timer(5000, 1);
			_hideTimer.addEventListener(TimerEvent.TIMER, onHideTimerComplete);
		}
		
		/**
		 * 注册tip
		 * @param showDelay 延迟显示tip的时间, 默认0表示不延时
		 * @param hideDelay 延迟隐藏tip的时间, 默认0表示不隐藏
		 */		
		public function registerTip(target:InteractiveObject, tip:DisplayObject, 
									showDelay:uint = 0, hideDelay:uint = 0, followMouse:Boolean = true):void
		{
			if (tip == null || target == null) return;
			if (_tipContainer == null)
				throw "tipContainer未初始化";
			
			_tipDic[target] = new TipVo(target, tip, showDelay, hideDelay, followMouse);
			
			target.addEventListener(MouseEvent.MOUSE_OVER, showTip);
			target.addEventListener(MouseEvent.MOUSE_OUT, hideTip);
		}
		
		/**
		 * 取消注册对象的tip
		 */		
		public function unregisterTip(target:InteractiveObject):void
		{
			var tipVo:TipVo = _tipDic[target];
			if (tipVo == null) return;
			
			tipVo.target.removeEventListener(MouseEvent.MOUSE_OVER, showTip);
			tipVo.target.removeEventListener(MouseEvent.MOUSE_OUT, hideTip);
			tipVo.target.removeEventListener(MouseEvent.MOUSE_MOVE, correctPosition);
			delete _tipDic[target];
		}
		
		/**
		 * 刷新tip的位置
		 */		
		private function correctPosition(e:MouseEvent = null):void
		{
			var xPos:int = _tipContainer.mouseX;
			var yPos:int = _tipContainer.mouseY;
			
			if (xPos + _currentTipVo.tip.width > _tipContainer.width)
			{
				xPos -= (_currentTipVo.tip.width + 10);
			}
			else 
			{
				xPos += 10;
			}
			
			if (yPos + _currentTipVo.tip.height > _tipContainer.height)
			{
				yPos -= (_currentTipVo.tip.height + 5);
			}
			else 
			{
				yPos += 10;
			}
			
			_currentTipVo.tip.x = xPos;
			_currentTipVo.tip.y = yPos;
		}
		
		/**
		 * 清除所有tip显示停止所有timer
		 */		
		private function clear():void
		{
			_showTimer.reset();
			_hideTimer.reset();
			
			while (_tipContainer.numChildren)
			{
				var target:InteractiveObject = _tipContainer.removeChildAt(0) as InteractiveObject;
				target.removeEventListener(MouseEvent.MOUSE_MOVE, correctPosition);
			}
		}
		
		/**
		 * 鼠标经过目标对象开始计时显示tip
		 */		
		private function showTip(e:MouseEvent):void
		{
			clear();
			
			var target:InteractiveObject = e.currentTarget as InteractiveObject;
			var tipVo:TipVo = _tipDic[target];
			if (tipVo == null) return;
			
			_currentTipVo = tipVo;
			
			_showTimer.delay = _currentTipVo.showDelay;
			_showTimer.start();
		}
		
		/**
		 * 显示延时Timer事件
		 */		
		private function onShowTimerComplete(e:TimerEvent):void
		{
			clear();
			if (!(_currentTipVo && _currentTipVo.target && _currentTipVo.target.stage)) return;
			
			_tipContainer.addChild(_currentTipVo.tip);
			correctPosition();
			
			//跟随鼠标
			if (_currentTipVo.followMouse)
				_currentTipVo.target.addEventListener(MouseEvent.MOUSE_MOVE, correctPosition);
				
			//有延迟要求
			if (_currentTipVo.hideDelay > 0)
			{
				_hideTimer.delay = _currentTipVo.hideDelay;
				_hideTimer.start();
			}
		}
		
		/**
		 * 隐藏延时Timer事件
		 */		
		private function onHideTimerComplete(e:TimerEvent):void
		{
			clear();
		}
		
		/**
		 * 鼠标移出清空tips
		 */		
		private function hideTip(e:MouseEvent):void
		{
			clear();
		}
		
		/**
		 * 返回所有已注册tip表
		 */		
		public function getTip(target:InteractiveObject):DisplayObject
		{
			var tipVo:TipVo = _tipDic[target];
			if (tipVo == null) return null;
			
			return tipVo.tip;
		}
		
		public static function getInstance():TipUtils
		{
			if (_instance == null)
			{
				_instance = new TipUtils();
			}
			return _instance;
		}
	}
}
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
/**
 * tip数据结构
 */
class TipVo
{
	public var target:InteractiveObject;
	public var tip:DisplayObject;
	public var showDelay:int;
	public var hideDelay:int;
	public var followMouse:Boolean;
	
	public function TipVo(target:InteractiveObject, tip:DisplayObject, 
						showDelay:int = 0, hideDelay:int = 5000, followMouse:Boolean = false)
	{
		this.target = target;
		this.tip = tip;
		this.showDelay = showDelay;
		this.hideDelay = hideDelay;
		this.followMouse = followMouse;
	}
}